//
//  HLCallViewController.m
//  YueYue
//
//  Created by hulu001 on 2023/6/19.
//

#import "HLCallViewController.h"

#import <FrameAccessor/FrameAccessor.h>
#import "HLRtcCallKit.h"
#import "HLFaceManager.h"
#import "HLCamera.h"
#import "HLGiftLiveShowCustomView.h"

#import "HLUserInfoRequest.h"

#import "HLGiftAttachment.h"
#import "HLRtcMoreView.h"
#import "HLRTCVideoView.h"
#import "HLRtcTokenModel.h"
#import "HLSystemRingTool.h"
#import "HLRtcUserInfoView.h"
#import "HLRtcInputView.h"
#import "HLRtcChatView.h"
#import "HLIMBackgroundView.h"
#import "HLGiftContainerView.h"
#import "HLRtcMatchSuccessView.h"
#import "HLRtcResultView.h"
#import "HLRtcRechargeView.h"
#import "HLMatchTipView.h"
#import "HLRtcExitView.h"
#import "GPLangCache.h"
#import "NSString+GPRegex.h"
#import "YMTranslacteRequest.h"

@interface HLCallViewController ()
<HLRtcCallKitDelegate,
HLRTCViceoViewDelegate,
HLCameraDelegate,
UIViewControllerTransitioningDelegate,
NIMChatManagerDelegate,
NIMSystemNotificationManagerDelegate,
HLRtcInputViewDelegate>
{
    CFAbsoluteTime _startNoTraceTime;
    
    CFAbsoluteTime _joinRoom;
    
    int _timerCount;
    
    int _remoteNotNetCount;// 远端没有网络计数
    
    int _femaleBlurCurrent;
    
}
@property (nonatomic,   copy) NSString *targetLang;
@property (nonatomic, strong) HLIMBackgroundView *backgroundView;  // 女生创建闪聊、等待时的背景
@property (nonatomic, strong) UIImageView *localAvatarView; // 本地（自己）头像 status:[YYCallStatusCreatingRoom、YYCallStatusWaitingMan]
@property (nonatomic, strong) UIImageView *remoteAvatarView;// 远端（好友）头像 status:[YYCallStatusJoiningRoom、YYCallStatusCalling、YYCallStatusCalled]
@property (nonatomic, strong) UIView *localFaceMask;  // 本地人脸的轮廓蒙版 status:[YYCallStatusWaitingMan]
@property (nonatomic, strong) UIView *localFaceView;  // 本地人脸 status:[YYCallStatusWaitingMan]
@property (nonatomic, strong) UILabel *faceErrorLabel; // 检测不到人脸，显示倒计时退出闪聊

@property (nonatomic, strong) UIVisualEffectView *femaleBlureView;
@property (nonatomic, strong) UILabel *localNameLabel; // status:[YYCallStatusCreatingRoom、YYCallStatusWaitingMan]
@property (nonatomic, strong) UILabel *remoteNameLabel;// status:[YYCallStatusJoiningRoom、YYCallStatusCalling、YYCallStatusCalled]
@property (nonatomic, strong) UILabel *statusLabel;// 状态文案 ‘正在创建房间...’、‘正在等待男生进入...‘、’正在连接中...‘、......
@property (nonatomic, strong) QMUILabel *priceLabel; // 扣费说明 ‘本次通话200金币/分钟，对方未接通不消化金币’ status:[YYCallStatusJoiningRoom、YYCallStatusCalling、YYCallStatusCalled]
@property (nonatomic, strong) UILabel *bottomLabel;// 底部label ‘闪聊匹配中 请保持脸部在屏幕中间’ status:[YYCallStatusCreatingRoom、YYCallStatusWaitingMan]
@property (nonatomic, strong) UIButton *cancelMatchBtn;// 取消闪聊的按钮 status:[YYCallStatusCreatingRoom、YYCallStatusWaitingMan]
@property (nonatomic, strong) QMUIButton *cancelCallingBtn;// 挂断 取消呼叫 status:[YYCallStatusCalling]
@property (nonatomic, strong) QMUIButton *rejectBtn; // 拒接按钮 status:[YYCallStatusCalled]
@property (nonatomic, strong) QMUIButton *acceptBtn; // 接听按钮 status:[YYCallStatusCalled]
@property (nonatomic, strong) QMUIButton *secretAcceptBtn; // 私密接听按钮 status:[YYCallStatusCalled]

// YYCallStatusInCall
@property (nonatomic, strong) HLRTCVideoView *localRenderView;     // 本地的渲染画面
@property (nonatomic, strong) HLRTCVideoView *remoteRenderView;    // 远端的渲染画面
@property (nonatomic, strong) QMUIButton *hangupBtnInCall;   // 聊天中的挂断
@property (nonatomic, strong) QMUIButton *giftBtnInCall;     // 礼物按钮
@property (nonatomic, strong) QMUIButton *chongBtnInCall;     // chongZhi按钮
@property (nonatomic, strong) HLMatchTipView *matchTipView;     // 匹配提示
@property (nonatomic, strong) QMUIButton *moreBtnInCall;     // 更多按钮
@property (nonatomic, strong) QMUIButton *cameraBtnInCall; // 摄像头开关按钮
@property (nonatomic, strong) HLGiftLiveShowCustomView * customGiftShow;// 礼物弹幕
@property (nonatomic, strong) HLRtcChatView *chatView; // 视频中的聊天View
@property (nonatomic, strong) QMUIButton *chatButton;// 点击吊起键盘输入聊天消息
@property (nonatomic, strong) HLRtcInputView *inputView;
@property (nonatomic, strong) HLRtcUserInfoView *inforView;// 显示计时器，昵称、头像、关注
@property (nonatomic, strong) HLRtcMoreView *moreView;


/**
 * 非UI
 */
@property (nonatomic, assign) HLRtcCallType callType;
@property (nonatomic, strong) HLUserInfoModel *otherUser; // 对方账号
@property (nonatomic, strong) HLUserInfoModel *myself;    // 自己账号
@property (nonatomic, assign) HLCallStatus initStatus; // 页面初始时的状态
@property (nonatomic, strong) NSTimer *inCallTimer; // 通话计时

/** 外部设备采集 */
@property(nonatomic, strong) HLCamera *mCamera;

@property (nonatomic, assign) BOOL isHideViewInCall; //是不隐藏多余的视图

/// 是否开启了自动接听
@property (nonatomic, assign) BOOL isAutoAnswerOn;

@property (nonatomic, assign) BOOL isFromMatch;
@property (nonatomic, strong) HLRtcMatchSuccessView *matchView;

@property (nonatomic, assign) BOOL cancelMatch;


@end

@implementation HLCallViewController


- (void)dealloc
{
    NSLog(@"%s", __func__);
    UIApplication.sharedApplication.idleTimerDisabled = NO;
    [HLRtcCallKit.sharedInstance removeDelegate:self];
    [NIMSDK.sharedSDK.chatManager removeDelegate:self];
    [NIMSDK.sharedSDK.systemNotificationManager removeDelegate:self];
    if (@available(iOS 11.0, *)) {
        [NSNotificationCenter.defaultCenter removeObserver:self name:UIScreenCapturedDidChangeNotification object:nil];
        [NSNotificationCenter.defaultCenter removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil];
    } else {
        // Fallback on earlier versions
    }
    [NSNotificationCenter.defaultCenter removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [NSNotificationCenter.defaultCenter removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.targetLang = @"zh"; // 默认zh
        self.modalPresentationStyle = UIModalPresentationOverFullScreen;
        [HLRtcCallKit.sharedInstance addDelegate:self];
        [NIMSDK.sharedSDK.chatManager addDelegate:self];
        [NIMSDK.sharedSDK.systemNotificationManager addDelegate:self];
        HLRtcCallKit.sharedInstance.timeOutSeconds = 30;
        if (@available(iOS 11.0, *)) {
            /// 注意：这个监听在倒计时3秒后才会触发
            [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(screenHot) name:UIScreenCapturedDidChangeNotification object:nil];
            [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(screenHot) name:UIApplicationUserDidTakeScreenshotNotification object:nil];
//            [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationWillResignActiveNotification object:nil];
        } else {
            // Fallback on earlier versions
        }
    }
    return self;
}

#pragma mark - lifeCycle
- (void)viewDidLoad {
    [super viewDidLoad];
    UIApplication.sharedApplication.idleTimerDisabled = YES;
    
    MJWeakSelf
    HLRtcCallKit.sharedInstance.tokenHandler = ^(uint64_t uid, void (^complete)(NSString *token, NSError *error)) {
        if (weakSelf.joinToken) {
            complete(weakSelf.joinToken , nil);
        } else {
            complete(nil, [NSError errorWithDomain:@"没有token" code:1111 userInfo:@{NSLocalizedDescriptionKey : @"没有token"}]);
        }
    };
    
    NSError *error = nil;
    [HLRtcCallKit.sharedInstance setLoudSpeakerMode:YES error:&error];
    if (error) {
        [QMUITips showWithText:error.localizedDescription];
    }
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    UIApplication.sharedApplication.idleTimerDisabled = YES;
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[HLFaceManager shareManager] onCameraChange];
    [UIApplication sharedApplication].idleTimerDisabled = NO;
}


#pragma mark ----- FaceUnity ----

- (HLCamera *)mCamera{
    
    if (_mCamera == nil) {
        
        _mCamera = [[HLCamera alloc] initWithCameraPosition:(AVCaptureDevicePositionFront) captureFormat:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange];
        _mCamera.delegate = self;
    }
    
    return _mCamera;
}

#pragma mark ----------FUCameraDelegate-----
static int rate = 0;
static NSTimeInterval oldTime = 0;
- (void)didOutputVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer{
    
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    
    // 相芯渲染
    [[HLFaceManager shareManager] renderItemsToPixelBuffer:pixelBuffer];
    
    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
    NERtcVideoFrame *videoFrame = [[NERtcVideoFrame alloc] init];
    videoFrame.format = kNERtcVideoFormatNV12;
    videoFrame.width = (uint32_t)CVPixelBufferGetWidth(pixelBuffer);
    videoFrame.height = (uint32_t)CVPixelBufferGetHeight(pixelBuffer);
    videoFrame.timestamp = 0;
    videoFrame.buffer = (void *)pixelBuffer;
    // push给云信
    [[NERtcEngine sharedEngine] pushExternalVideoFrame:videoFrame];
    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}

#pragma mark - <云信的采集回调>

- (void)onVideoFrameCaptured:(CVPixelBufferRef)bufferRef rotation:(NERtcVideoRotationType)rotation
{
    [HLFaceManager.shareManager renderItemsToPixelBuffer:bufferRef];
}

#pragma mark - ----

- (void)createRoom
{
    self.initStatus = HLCallStatusCreatingRoom;
    
    self.status = HLCallStatusCreatingRoom;
}

- (void)joinRoom:(NSString *)roomId
        fromUser:(HLUserInfoModel *)fromUser
        duration:(NSInteger)duration
           token:(nonnull NSString *)token
{
    self.roomID = roomId;
    self.otherUser = fromUser;
    
    self.initStatus = HLCallStatusJoiningRoom;
    self.isFromMatch = (fromUser.videoType == HLRtcCallVideoTypeHeartVideo);
    
    self.status = HLCallStatusJoiningRoom;
    
    if (roomId == nil || roomId.length == 0) {
        return;
    }

    NSString *channelId = [roomId componentsSeparatedByString:@"_"].firstObject;
    
    self.joinToken = token;
    self.avaiableDuration = duration;
    self.avaiableInitDuration = duration;
    [HLRtcCallKit.sharedInstance JoinChannel:channelId completion:^(NSError * _Nullable error) {
        if (error) {
            [QMUITips showWithText:error.localizedDescription];
            [self destroyVC];
        } else {
        }
    }];
}

- (void)callUser:(HLUserInfoModel *)toUserInfor
        duration:(NSInteger)duration
           token:(nonnull NSString *)token
{
    self.callType = HLRtcCallTypeVideo;
    self.initStatus = HLCallStatusCalling;
    
    self.otherUser = toUserInfor;
    self.status = HLCallStatusCalling;
    self.isFromMatch = (toUserInfor.videoType == HLRtcCallVideoTypeHeartVideo);
    self.joinToken = token;
    self.avaiableDuration = duration;
    self.avaiableInitDuration = duration;
    
    [HLRtcCallKit.sharedInstance call:toUserInfor.userId type:HLRtcCallTypeVideo videoType:toUserInfor.videoType completion:^(NSError * _Nullable error) {
        NSLog(@"呼叫 %@ userID : %@", toUserInfor.nickName, toUserInfor.userId);
        if (!error) {
        } else {
            [QMUITips showWithText:error.localizedDescription];
            [self destroyVC];
        }
    }];
    
    /*
     去查询对方的的用户信息，更新 呼叫/被呼叫 的背景、头像、昵称
     */
    if (toUserInfor.userId.length > 0) {
        [self requestUserInfor:toUserInfor.userId];
    }
}

- (void)matchUser:(HLUserInfoModel *)userInfor
         duration:(NSInteger)duration
            token:(NSString *)token
{
    self.isFromMatch = YES;
    self.initStatus = HLCallStatusCalling;
    self.otherUser = userInfor;
    
    self.joinToken = token;
    self.avaiableDuration = duration;
    self.avaiableInitDuration = duration;
    
    self.status = HLCallStatusNone;
    [self.view addSubview:self.matchView];
    self.matchView.matchUserModel = userInfor;
    [HLRtcCallKit.sharedInstance setupLocalView:nil];
    [HLRtcCallKit.sharedInstance setupLocalView:_matchView.rtcView];
    
    [self match_timer:3];
    
    /*
     去查询对方的的用户信息，更新 呼叫/被呼叫 的背景、头像、昵称
     */
    if (userInfor.userId.length > 0) {
        [self requestUserInfor:userInfor.userId];
    }
}

- (void)match_timer:(NSInteger)count
{
    if (self.cancelMatch) {
        return;
    }
    MJWeakSelf
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    
        if (count == 0) {
            
            weakSelf.matchView.statusLabel.text = @"连接中…";
            //[weakSelf.matchView startSVG2];
            self->_status = HLCallStatusCalling; // 使用self->_status 而不是self.status， 因为不需要去触发set方法
            [HLRtcCallKit.sharedInstance call:weakSelf.otherUser.userId type:HLRtcCallTypeVideo videoType:HLRtcCallVideoTypeHeartVideo completion:^(NSError * _Nullable error) {
                if (!error) {
                } else {
                    weakSelf.matchView.statusLabel.text = @"连接失败";
                    [weakSelf destroyVC];
//                    weakSelf.matchView.rematchButton.hidden = NO;
//
//                    weakSelf.matchView.rematchBlock = ^{
//                        [weakSelf destroyVC];
//                    };
                }
            }];
        } else {
            self.matchView.statusLabel.text = [NSString stringWithFormat:@"%zds后即将开始", count];
            [self match_timer:count-1];
        }
    });
}

- (void)calledFormCallUser:(HLUserInfoModel *)fromUserInfor
{
    self.callType = HLRtcCallTypeVideo;
    self.initStatus = HLCallStatusCalled;
    
    self.otherUser = fromUserInfor;
    
    self.status = HLCallStatusCalled;
    
    /*
     去查询对方的的用户信息，更新 呼叫/被呼叫 的背景、头像、昵称
     */
    [self requestUserInfor:fromUserInfor.userId];
    /*
     检查权限
     */
    [self checkServiceEnable:^(BOOL result) {
    }];
}

- (void)accept:(HLUserInfoModel *)fromUserInfor
{
    self.otherUser = fromUserInfor;
    self.initStatus = HLCallStatusCalled;
    self.status = HLCallStatusJoiningRoom;
    [self acceptBtn:nil];
}
    
- (void)requestUserInfor:(NSString *)uid
{
    HLUserInfoRequest *userInfoRequest = [[HLUserInfoRequest alloc] initWithUserId:uid];
    [userInfoRequest startWithCompletionBlockWithSuccess:^(__kindof HLUserInfoRequest * _Nonnull request) {
        if (request.isSuccess){
            
            self.otherUser = [request user];
            if (self.status == HLCallStatusCalling) {
                [self layoutCalling];
            } else if (self.status == HLCallStatusCalled) {
                [self layoutCalled];
            }
        }
    } failure:nil];
    
}

/// 关注请求
- (void)requestFollow
{
    MJWeakSelf
    [HLUIHelper followWithUserId:self.otherUser.userId follow:NO callback:^(BOOL isConfirm) {
        if (isConfirm){
            self.otherUser.followType = @"0";
            self.inforView.userM = self.otherUser;
            HLRtcMessageModel *msg = [[HLRtcMessageModel alloc] init];
            msg.type = 1000;
            msg.ext = [NSString stringWithFormat:@"公告：你关注了%@", weakSelf.otherUser.nickName];
            [weakSelf.chatView addMessage:msg];
        }
    }];
    
}

- (void)setOtherUser:(HLUserInfoModel *)otherUser
{
    _otherUser = otherUser;
    
    MJWeakSelf
    [GPLangCache.shareInstance fetchLangForKey:otherUser.userId clientID:@"Platform" completion:^(NSString * _Nonnull lang) {
        weakSelf.targetLang = lang;
    }];
}

#pragma mark - <状态控制>

- (void)setStatus:(HLCallStatus)status
{
    _status = status;
    
    switch (status) {
        case HLCallStatusCreatingRoom: // 正在创建房间
        {
            // 布局
            [self layoutCreatingRoom];
            // 逻辑
            [HLRtcCallKit.sharedInstance createChannel:HLRtcCallTypeVideo completion:^(NSString * _Nullable channelID, NSError * _Nullable error) {
                self->_joinRoom = CFAbsoluteTimeGetCurrent();
                if (error) {
                    [QMUITips showWithText:error.localizedDescription];
                } else {
                    self.roomID = channelID;
                    NSLog(@"成功创建频道");
                    self.status = HLCallStatusWaitingMan;
                    [HLRtcCallKit.sharedInstance JoinChannel:channelID completion:^(NSError * _Nullable error) {
                        if (error) {
                            [QMUITips showWithText:error.localizedDescription];
                        } else {
                            NSLog(@"成功加入频道");
                            /** 初始化 Faceu */
                            [self.mCamera startCapture];
                            [self.mCamera changeSessionPreset:AVCaptureSessionPreset640x480];
                            [self.mCamera changeVideoFrameRate:14];
                            [UIApplication sharedApplication].idleTimerDisabled = YES;
                            [HLRtcCallKit.sharedInstance setupLocalView:nil];
                            [HLRtcCallKit.sharedInstance setupLocalView:self.localFaceView];
                        }
                    }];
                }
            }];
        }
            break;
        case HLCallStatusWaitingMan: // 正在等待男方加入
        {
            [self layoutWaitingMan];
        }
            break;
        case HLCallStatusJoiningRoom: // 男方正在进入闪聊，连接中
        {
            [self layoutJoiningShanLiao];
        }
            break;
        case HLCallStatusCalling: // 正在呼叫
        {
            [self layoutCalling];
        }
            break;
        case HLCallStatusCalled: // 被呼叫
        {
            [self layoutCalled];
        }
            break;
        case HLCallStatusInCall: // 通话中
        {
            NSLog(@"status:YYCallStatusInCall");
            if (_matchView) {
                [self.matchView removeFromSuperview];
            }
            self.matchView = nil;
            [self layoutInCall];
            // 相机采集设置
            [self.mCamera changeSessionPreset:AVCaptureSessionPreset640x480];
            [self.mCamera changeVideoFrameRate:14];
            [self.mCamera startCapture];
            
            // 渲染本地画面
            [HLRtcCallKit.sharedInstance changeLocalView:self.localRenderView];
        }
            break;
            
        default:
            break;
    }
}

#pragma mark - <UI>

- (HLIMBackgroundView *)backgroundView {
    if (!_backgroundView) {
        _backgroundView = [[HLIMBackgroundView alloc] initWithFrame:UIScreen.mainScreen.bounds];
    }
    return _backgroundView;
}

- (UIImageView *)localAvatarView {
    if (!_localAvatarView) {
        _localAvatarView = [UIImageView.alloc initWithFrame:CGRectMake(16, NavigationContentTopConstant + 9, 64, 64)];
        _localAvatarView.layer.cornerRadius = 32;
        _localAvatarView.layer.masksToBounds = YES;
        _localAvatarView.image = [HLUIHelper avatarPlaceholder];
    }
    return _localAvatarView;
}

- (UIImageView *)remoteAvatarView {
    if (!_remoteAvatarView) {
        _remoteAvatarView = [[UIImageView alloc] init];
        _remoteAvatarView.layer.cornerRadius = 8;
        _remoteAvatarView.layer.masksToBounds = YES;
        _remoteAvatarView.layer.borderColor = UIColor.whiteColor.CGColor;
        _remoteAvatarView.layer.borderWidth = 1.f;
        _remoteAvatarView.image = [HLUIHelper avatarBigPlaceholder];
        _remoteAvatarView.contentMode = UIViewContentModeScaleAspectFill;
    }
    return _remoteAvatarView;
}

- (UILabel *)localNameLabel {
    if (!_localNameLabel) {
        _localNameLabel = [UILabel.alloc init];
        _localNameLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
        _localNameLabel.textColor = UIColor.whiteColor;
    }
    return _localNameLabel;
}

- (UILabel *)remoteNameLabel
{
    if (!_remoteNameLabel) {
        _remoteNameLabel = [UILabel.alloc init];
        _remoteNameLabel.textColor = UIColor.whiteColor;
        _remoteNameLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightMedium];
    }
    return _remoteNameLabel;
}

- (UILabel *)statusLabel
{
    if (!_statusLabel) {
        _statusLabel = [UILabel.alloc init];
        _statusLabel.font = [UIFont systemFontOfSize:15];
        _statusLabel.textColor = UIColor.whiteColor;
    }
    return _statusLabel;
}

- (UILabel *)bottomLabel
{
    if (!_bottomLabel) {
        _bottomLabel = [UILabel.alloc init];
        _bottomLabel.text = @"闪聊匹配中 请保持脸部在屏幕中间";
        _bottomLabel.font = [UIFont systemFontOfSize:12];
        _bottomLabel.textColor = HLTextColor3;
        [_bottomLabel sizeToFit];
    }
    return _bottomLabel;
}

- (QMUILabel *)priceLabel
{
    if (!_priceLabel) {
        _priceLabel = [[QMUILabel alloc] qmui_initWithFont:UIFontMake(12) textColor:[UIColorWhite colorWithAlphaComponent:0.6]];
        _priceLabel.contentEdgeInsets = UIEdgeInsetsMake(10, 12, 10, 12);
        _priceLabel.backgroundColor = [UIColorBlack colorWithAlphaComponent:0.3];
        
        NSString *string = @"";
        if (self.otherUser.videoType == HLRtcCallVideoTypeHeartVideo) {
            string = [NSString stringWithFormat:@"TIPS:本次通话折扣价 99金币/30s"];
        } else {
            string = [NSString stringWithFormat:@"TIPS:本次通话折扣价 %@ 金币/分钟", self.videoPrice];
        }
        
        _priceLabel.text = string ;
    
        _priceLabel.layer.masksToBounds = YES;
        _priceLabel.layer.cornerRadius = 4;
    }
    return _priceLabel;
}
- (UIVisualEffectView *)femaleBlureView
{
    if (!_femaleBlureView){
        _femaleBlureView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect qmui_effectWithBlurRadius:30]];
        _femaleBlureView.frame = CGRectMake(0, SCREEN_HEIGHT * 0.5 / 2, SCREEN_WIDTH, SCREEN_HEIGHT * 0.5);
    }
    return _femaleBlureView;
}
- (UIButton *)cancelMatchBtn
{
    if (!_cancelMatchBtn) {
        _cancelMatchBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _cancelMatchBtn.bounds = CGRectMake(0, 0, 128, 40);
        [_cancelMatchBtn setTitle:@"取消闪聊匹配" forState:UIControlStateNormal];
        [_cancelMatchBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
        _cancelMatchBtn.titleLabel.font = [UIFont systemFontOfSize:16];
        _cancelMatchBtn.layer.cornerRadius = 20;
        _cancelMatchBtn.layer.masksToBounds = YES;
        _cancelMatchBtn.layer.borderColor = UIColor.whiteColor.CGColor;
        _cancelMatchBtn.layer.borderWidth = 1.f;
        [_cancelMatchBtn addTarget:self action:@selector(cancelMatchEvent:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _cancelMatchBtn;
}

- (QMUIButton *)cancelCallingBtn
{
    if (!_cancelCallingBtn) {
        _cancelCallingBtn = [[QMUIButton alloc] init];
        [_cancelCallingBtn setImage:UIImageMake(@"hangup") forState:UIControlStateNormal];
        [_cancelCallingBtn setTitle:@"挂断" forState:UIControlStateNormal];
        _cancelCallingBtn.imagePosition = QMUIButtonImagePositionTop;
        _cancelCallingBtn.spacingBetweenImageAndTitle = 4;
        [_cancelCallingBtn setTitleColor:[UIColorWhite colorWithAlphaComponent:0.5] forState:UIControlStateNormal];
        [_cancelCallingBtn.titleLabel setFont:UIFontMake(13)];
        [_cancelCallingBtn addTarget:self action:@selector(cancelCallingEvent:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _cancelCallingBtn;
}

- (QMUIButton *)rejectBtn
{
    if (!_rejectBtn) {
        _rejectBtn = [[QMUIButton alloc] init];
        [_rejectBtn setImage:UIImageMake(@"hangupIncall") forState:UIControlStateNormal];
        [_rejectBtn addTarget:self action:@selector(rejectBtn:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _rejectBtn;
}

- (QMUIButton *)acceptBtn
{
    if (!_acceptBtn) {
        _acceptBtn = [[QMUIButton alloc] init];
        [_acceptBtn setImage:[UIImage imageNamed:@"accept"] forState:UIControlStateNormal];
        [_acceptBtn setTitle:@"接听" forState:UIControlStateNormal];
        _acceptBtn.imagePosition = QMUIButtonImagePositionTop;
        _acceptBtn.spacingBetweenImageAndTitle = 4;
        [_acceptBtn setTitleColor:[UIColorWhite colorWithAlphaComponent:0.5] forState:UIControlStateNormal];
        [_acceptBtn.titleLabel setFont:UIFontMake(13)];
        [_acceptBtn addTarget:self action:@selector(acceptBtn:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _acceptBtn;
}

- (QMUIButton *)secretAcceptBtn
{
    if (!_secretAcceptBtn) {
        _secretAcceptBtn = [[QMUIButton alloc] init];
        [_secretAcceptBtn setImage:[UIImage imageNamed:@"secret_accept"] forState:UIControlStateNormal];
        [_secretAcceptBtn addTarget:self action:@selector(secretAcceptBtn:) forControlEvents:UIControlEventTouchUpInside];
        _secretAcceptBtn.imagePosition = QMUIButtonImagePositionTop;
        _secretAcceptBtn.spacingBetweenImageAndTitle = 4;
        [_secretAcceptBtn setTitleColor:[UIColorWhite colorWithAlphaComponent:0.5] forState:UIControlStateNormal];
        [_secretAcceptBtn.titleLabel setFont:UIFontMake(13)];
        [_secretAcceptBtn setTitle:@"私密接听" forState:UIControlStateNormal];
    }
    return _secretAcceptBtn;
}


- (UIView *)localFaceView
{
    if (!_localFaceView) {
        _localFaceView = [UIView.alloc initWithFrame:CGRectMake(0, 0, 120, 180)];
    }
    return _localFaceView;
}

- (UILabel *)faceErrorLabel
{
    if (!_faceErrorLabel) {
        _faceErrorLabel = [UILabel.alloc init];
        _faceErrorLabel.backgroundColor = HLTextColor3;
        _faceErrorLabel.textColor = UIColor.whiteColor;
        _faceErrorLabel.font = [UIFont systemFontOfSize:12];
        _faceErrorLabel.textAlignment = NSTextAlignmentCenter;
    }
    return _faceErrorLabel;
}

- (UIView *)localFaceMask
{
    if (!_localFaceMask) {
        _localFaceMask = [UIView.alloc initWithFrame:CGRectMake(0, 0, 120, 180)];
        UIImageView *mask = [UIImageView.alloc initWithFrame:CGRectMake(0, 0, 120, 152)];
        mask.image = [UIImage imageNamed:@"faceMask"];
        [_localFaceMask addSubview:mask];
        UILabel *label = [UILabel.alloc initWithFrame:CGRectMake(0, mask.bottom + 4, 120, 180 - 152 - 4)];
        label.backgroundColor = [UIColor.blackColor colorWithAlphaComponent:0.5];
        label.text = @"保持脸部在屏幕中";
        label.textColor = UIColor.whiteColor;
        label.font = [UIFont systemFontOfSize:12];
        label.textAlignment = NSTextAlignmentCenter;
        [_localFaceMask addSubview:label];
    }
    return _localFaceMask;
}

- (HLRTCVideoView *)localRenderView
{
    if (!_localRenderView) {
        _localRenderView = [[HLRTCVideoView alloc] init];
        _localRenderView.isSmall = YES; // 默认小画面
        _localRenderView.delegate = self;
        _localRenderView.layer.cornerRadius = 8;
        _localRenderView.layer.masksToBounds = YES;
    }
    return _localRenderView;
}

- (HLRtcFloatingWindow *)smallWindow
{
    if (!_smallWindow) {
        _smallWindow = [[HLRtcFloatingWindow alloc] initWithFrame:CGRectMake(SCREEN_WIDTH - 120, NavigationBarHeight, 120, 180)];
        _smallWindow.isKeepBounds = YES;
        _smallWindow.layer.cornerRadius = 8;
        _smallWindow.layer.masksToBounds = YES;
    }
    return _smallWindow;
}


- (HLRTCVideoView *)remoteRenderView
{
    if (!_remoteRenderView) {
        _remoteRenderView = [[HLRTCVideoView alloc] init];
        _remoteRenderView.frame = self.view.bounds;
        _remoteRenderView.delegate = self;
    }
    return _remoteRenderView;
}

- (QMUIButton *)hangupBtnInCall
{
    if (!_hangupBtnInCall) {
        _hangupBtnInCall = [[QMUIButton alloc] init];
        [_hangupBtnInCall setImage:[UIImage imageNamed:@"hangupIncall"] forState:UIControlStateNormal];
        [_hangupBtnInCall addTarget:self action:@selector(hangupBtnInCall:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _hangupBtnInCall;
}

- (QMUIButton *)giftBtnInCall
{
    if (!_giftBtnInCall) {
        _giftBtnInCall = [[QMUIButton alloc] init];
        [_giftBtnInCall setImage:[UIImage imageNamed:@"rtc_gift"] forState:UIControlStateNormal];
        [_giftBtnInCall addTarget:self action:@selector(giftBtnInCall:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _giftBtnInCall;
}

- (QMUIButton *)moreBtnInCall
{
    if (!_moreBtnInCall) {
        _moreBtnInCall = [[QMUIButton alloc] init];
        [_moreBtnInCall setImage:[UIImage imageNamed:@"rtc_more"] forState:UIControlStateNormal];
        [_moreBtnInCall addTarget:self action:@selector(moreButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _moreBtnInCall;
}

- (QMUIButton *)chongBtnInCall
{
    if (!_chongBtnInCall) {
        _chongBtnInCall = [[QMUIButton alloc] init];
        [_chongBtnInCall setImage:[UIImage imageNamed:@"rtc_chong"] forState:UIControlStateNormal];
        [_chongBtnInCall addTarget:self action:@selector(rechargeBtnInCall:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _chongBtnInCall;
}

- (HLMatchTipView *)matchTipView
{
    if (!_matchTipView) {
        _matchTipView = [[HLMatchTipView alloc] init];
        _matchTipView.hidden = YES;
        MJWeakSelf
        _matchTipView.callback = ^(BOOL isCall) {
            if (isCall){
                weakSelf.isFromMatch = NO;
                weakSelf.matchTipView.hidden = YES;
            }
        };
    }
    return _matchTipView;
}


- (HLRtcUserInfoView *)inforView
{
    if (!_inforView) {
        _inforView = [[HLRtcUserInfoView alloc] init];
        MJWeakSelf
        _inforView.followButton.qmui_tapBlock = ^(__kindof UIControl *sender) {
            [weakSelf requestFollow];
        };
    }
    return _inforView;
}

- (HLRtcMoreView *)moreView
{
    if (!_moreView){
        _moreView = [[HLRtcMoreView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 210)];
        [_moreView.muteButton addTarget:self action:@selector(muteEvent:) forControlEvents:UIControlEventTouchUpInside];
        [_moreView.switchCameraButton addTarget:self action:@selector(switchCameraEvent:) forControlEvents:UIControlEventTouchUpInside];
        [_moreView.cameraButton addTarget:self action:@selector(closeCameraEvent:) forControlEvents:UIControlEventTouchUpInside];
        [_moreView.smallButton addTarget:self action:@selector(smallWindowEvent:) forControlEvents:UIControlEventTouchUpInside];
    }
    
    return _moreView;
}

- (HLGiftLiveShowCustomView *)customGiftShow{
    if (!_customGiftShow) {
        _customGiftShow = [HLGiftLiveShowCustomView addToView:self.view y: self.view.centerY-60];
        
        _customGiftShow.addMode = HLGiftLiveAddModeAdd;
        [_customGiftShow setMaxGiftCount:1];
        [_customGiftShow setShowMode:HLGiftLiveShowModeFromTopToBottom];
        [_customGiftShow setAppearModel:HLGiftLiveAppearModeLeft];
        [_customGiftShow setHiddenModel:HLGiftLiveHiddenModeLeft];
        [_customGiftShow enableInterfaceDebug:NO];
    }
    return _customGiftShow;
}

- (HLRtcChatView *)chatView
{
    if (!_chatView) {
        _chatView = [[HLRtcChatView alloc] init];
    }
    return _chatView;
}

- (QMUIButton *)chatButton
{
    if (!_chatButton) {
        _chatButton = [[QMUIButton alloc] init];
        _chatButton.backgroundColor = [UIColorBlack colorWithAlphaComponent:0.3];
        _chatButton.layer.cornerRadius = 12;
        _chatButton.layer.masksToBounds = YES;
        _chatButton.layer.borderColor = [UIColorWhite colorWithAlphaComponent:0.2].CGColor;
        _chatButton.layer.borderWidth = 1.6;
        _chatButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
        _chatButton.contentEdgeInsets = UIEdgeInsetsMake(12, 16, 12, 16);
        _chatButton.titleLabel.font = [UIFont systemFontOfSize:12];
        [_chatButton setTitle:@"说点什么…" forState:UIControlStateNormal];
        [_chatButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
        [_chatButton addTarget:self action:@selector(chatButtonEvent:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _chatButton;
}

- (HLRtcMatchSuccessView *)matchView
{
    if (!_matchView) {
        _matchView = [[HLRtcMatchSuccessView alloc] initWithFrame:self.view.bounds type:1];
        MJWeakSelf
        _matchView.backBlock = ^{
            weakSelf.cancelMatch = YES;// 取消匹配，倒计时计时器里判断结束，不进行呼叫
            [HLSystemRingTool.shareInstance finishPlay];
            if (weakSelf.status == HLCallStatusCalling) {
                [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
                    [HLSystemRingTool.shareInstance finishPlay];
                    [weakSelf destroyVC];
                }];
            } else {
                [weakSelf destroyVC];
            }
        };
    }
    return _matchView;
}

#pragma mark - <layout>

/// 创建房间
- (void)layoutCreatingRoom
{
    // 默认先隐藏所有的控件
    
    NSArray *avaiableViews = @[self.backgroundView, self.localAvatarView, self.localNameLabel, self.statusLabel, self.cancelMatchBtn, self.bottomLabel];
    [self updateAvailableViews:avaiableViews];
    
    // 显示需要的
    [self.view addSubview:self.backgroundView];
    [self.view addSubview:self.localAvatarView]; // 自己的头像
    [self.view addSubview:self.localNameLabel]; // 自己的名字
    [self.view addSubview:self.statusLabel];    // 当前状态
    [self.view addSubview:self.cancelMatchBtn]; // 女性取消闪聊匹配的按钮
    [self.view addSubview:self.bottomLabel];    // 底部的提示
    
    self.backgroundView.hidden  = NO;
    self.localNameLabel.hidden  = NO;
    self.statusLabel.hidden     = NO;
    self.cancelMatchBtn.hidden  = NO;
    self.bottomLabel.hidden     = NO;
    
    [self.localAvatarView sd_setImageWithURL:[NSURL URLWithString:HLRunTime.shareInstance.mine.avatar] placeholderImage:[HLUIHelper avatarBigPlaceholder]];
    self.localAvatarView.left = 16;
    self.localAvatarView.top = StatusBarHeightConstant + 9;
    
    self.localNameLabel.text = HLRunTime.shareInstance.mine.nickName;
    [self.localNameLabel sizeToFit];
    self.localNameLabel.left = self.localAvatarView.right + 16;
    self.localNameLabel.top = self.localAvatarView.top + 8;
    
    self.statusLabel.text = @"正在创建房间中…";
    [self.statusLabel sizeToFit];
    self.statusLabel.left = self.localNameLabel.left;
    self.statusLabel.top = self.localNameLabel.bottom + 4;
    
    self.bottomLabel.centerX = self.view.middleX;
    self.bottomLabel.bottom = self.view.height - NavigationContentTopConstant - 16;
    
    self.cancelMatchBtn.centerX = self.view.middleX;
    self.cancelMatchBtn.bottom = self.bottomLabel.top - 40;
}

/// 等待男人加入
- (void)layoutWaitingMan
{
    // 显示需要的
    [self.view addSubview:self.backgroundView];
    [self.view addSubview:self.localAvatarView]; // 自己的头像
    [self.view addSubview:self.localNameLabel]; // 自己的名字
    [self.view addSubview:self.statusLabel];    // 当前状态
    [self.view addSubview:self.cancelMatchBtn]; // 女性取消闪聊匹配的按钮
    [self.view addSubview:self.bottomLabel];    // 底部的提示
    [self.view addSubview:self.localFaceView];  // 人脸
    [self.view addSubview:self.localFaceMask];  // 人脸蒙版
    [self.view addSubview:self.faceErrorLabel];
    
    self.backgroundView.hidden  = NO;
    self.localNameLabel.hidden  = NO;
    self.statusLabel.hidden     = NO;
    self.cancelMatchBtn.hidden  = NO;
    self.bottomLabel.hidden     = NO;
    self.localFaceView.hidden   = NO;
    self.localFaceMask.hidden   = NO;
    self.faceErrorLabel.hidden  = YES;
    self.localAvatarView.hidden = NO;
    
    [self.localAvatarView sd_setImageWithURL:[NSURL URLWithString:HLRunTime.shareInstance.mine.avatar] placeholderImage:[HLUIHelper avatarPlaceholder]];
    self.localAvatarView.left = 16;
    self.localAvatarView.top = StatusBarHeightConstant + 9;
    
    self.localNameLabel.text = HLRunTime.shareInstance.mine.nickName;
    [self.localNameLabel sizeToFit];
    self.localNameLabel.left = self.localAvatarView.right + 16;
    self.localNameLabel.top = self.localAvatarView.top + 8;
    
    self.statusLabel.text = @"等待你的男主进入…";
    [self.statusLabel sizeToFit];
    self.statusLabel.left = self.localNameLabel.left;
    self.statusLabel.top = self.localNameLabel.bottom + 4;
    
    self.bottomLabel.centerX = self.view.middleX;
    self.bottomLabel.bottom = self.view.height - SafeAreaInsetsConstantForDeviceWithNotch.bottom - 16;
    
    
    self.cancelMatchBtn.centerX = self.view.middleX;
    self.cancelMatchBtn.bottom = self.bottomLabel.top - 40;
    
    
    self.localFaceView.top = StatusBarHeightConstant + 73;
    self.localFaceView.right = self.view.width - 16;
    self.localFaceMask.centerX = self.localFaceView.centerX;
    self.localFaceMask.top = self.localFaceView.top;
    
    self.faceErrorLabel.viewSize = CGSizeMake(self.localFaceView.width, 30);
    self.faceErrorLabel.bottom = self.localFaceView.bottom;
    self.faceErrorLabel.centerX = self.localFaceView.centerX;
    
}

/// 男的加入房间
- (void)layoutJoiningShanLiao
{
    [self.view addSubview:self.backgroundView];
    self.backgroundView.backgroundColor = [UIColor blackColor];
    
    [self.view addSubview:self.remoteAvatarView];
    self.remoteAvatarView.center = self.view.middlePoint;
    self.remoteAvatarView.centerY = self.view.height * 0.5 * 0.8; // 向上偏移0.2倍
    [self.remoteAvatarView sd_setImageWithURL:[NSURL URLWithString:self.otherUser.avatar] placeholderImage:[HLUIHelper avatarPlaceholder]];
    
    [self.view addSubview:self.remoteNameLabel];
    self.remoteNameLabel.text = self.otherUser.nickName;
    [self.remoteNameLabel sizeToFit];
    self.remoteNameLabel.centerX = self.view.middleX;
    self.remoteNameLabel.top = self.remoteAvatarView.bottom + 32;
    
    [self.view addSubview:self.statusLabel];
    self.statusLabel.text = @"正在接通中…";
    [self.statusLabel sizeToFit];
    self.statusLabel.centerX = self.view.middleX;
    self.statusLabel.top = self.remoteNameLabel.bottom + 12;
    
    [self.view addSubview:self.priceLabel];
    [self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(16);
        make.right.mas_equalTo(-16);
        make.bottom.mas_equalTo(-(SafeAreaInsetsConstantForDeviceWithNotch.bottom + 16));
    }];
}

/// 正在呼叫别人
- (void)layoutCalling
{
    // 默认先隐藏所有的控件
    [self.view addSubview:self.backgroundView];
    [self.backgroundView.imageView sd_setImageWithURL:[NSURL URLWithString:self.otherUser.avatar] placeholderImage:[HLUIHelper avatarBigPlaceholder]];
    
    [self.view addSubview:self.inforView];
    [self.inforView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(12);
        make.top.mas_equalTo(StatusBarHeightConstant);
    }];
    self.inforView.userM = self.otherUser;
    self.inforView.durationLabel.text = @"等待接听中…";
    
    [self.view addSubview:self.rejectBtn];
    [self.rejectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.inforView);
        make.size.mas_equalTo(24);
        make.right.mas_equalTo(-12);
    }];
    
    [self.view addSubview:self.remoteAvatarView];
    [self.remoteAvatarView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.mas_equalTo(-12);
        make.top.equalTo(self.inforView.mas_bottom).offset(12);
        make.size.mas_equalTo(CGSizeMake(88, 120));
    }];
    [self.remoteAvatarView sd_setImageWithURL:[NSURL URLWithString:HLRunTime.shareInstance.mine.avatar] placeholderImage:[HLUIHelper avatarBigPlaceholder]];
    [self.mCamera startCapture];
    [HLRtcCallKit.sharedInstance setupLocalView:nil];
    [HLRtcCallKit.sharedInstance setupLocalView:self.remoteAvatarView];

    
    
    
    [self.view addSubview:self.statusLabel];
    [self.statusLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(0);
        make.centerY.mas_equalTo(SCREEN_HEIGHT * 0.2);
    }];
    self.statusLabel.text = @"正在呼叫…";

    
    [self.view addSubview:self.priceLabel];
    [self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(0);
        make.top.equalTo(self.statusLabel.mas_bottom).offset(12);
    }];
    
//    [self.view addSubview:self.cancelCallingBtn];
//    [self.cancelCallingBtn mas_makeConstraints:^(MASConstraintMaker *make) {
//        make.centerX.mas_equalTo(0);
//        make.top.equalTo(self.priceLabel.mas_bottom).offset(34);
//    }];
}

/// 被呼叫
- (void)layoutCalled
{
    // 默认先隐藏所有的控件
    [self.view addSubview:self.backgroundView];
    [self.backgroundView.imageView sd_setImageWithURL:[NSURL URLWithString:self.otherUser.avatar] placeholderImage:[HLUIHelper avatarBigPlaceholder]];
    
    [self.view addSubview:self.inforView];
    [self.inforView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(12);
        make.top.mas_equalTo(StatusBarHeightConstant);
    }];
    self.inforView.userM = self.otherUser;
    self.inforView.durationLabel.text = @"等待接听中…";
    
    [self.view addSubview:self.rejectBtn];
    [self.rejectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.inforView);
        make.size.mas_equalTo(24);
        make.right.mas_equalTo(-12);
    }];
    
    [self.view addSubview:self.remoteAvatarView];
    [self.remoteAvatarView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.mas_equalTo(-12);
        make.top.equalTo(self.inforView.mas_bottom).offset(12);
        make.size.mas_equalTo(CGSizeMake(88, 120));
    }];
    [self.remoteAvatarView sd_setImageWithURL:[NSURL URLWithString:HLRunTime.shareInstance.mine.avatar] placeholderImage:[HLUIHelper avatarBigPlaceholder]];
    
    [self.mCamera startCapture];
    [HLRtcCallKit.sharedInstance setupLocalView:nil];
    [HLRtcCallKit.sharedInstance setupLocalView:self.remoteAvatarView];

    
    [self.view addSubview:self.statusLabel];
    [self.statusLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(0);
        make.centerY.mas_equalTo(SCREEN_HEIGHT * 0.2);
    }];
    self.statusLabel.text = @"邀请您视频通话…";

    
    [self.view addSubview:self.priceLabel];
    [self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(0);
        make.top.equalTo(self.statusLabel.mas_bottom).offset(12);
    }];

    [self.view addSubview:self.secretAcceptBtn];
    [self.secretAcceptBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(-90);
        make.top.equalTo(self.priceLabel.mas_bottom).offset(34);
    }];
    
    [self.view addSubview:self.acceptBtn];
    [self.acceptBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(90);
        make.top.equalTo(self.secretAcceptBtn);
    }];
    
    
}

/// 通话中
- (void)layoutInCall
{
    [self.view addSubview:self.remoteRenderView];
    [self.view addSubview:self.chatView];
    [self.view addSubview:self.localRenderView];
    [self.view addSubview:self.hangupBtnInCall];
    [self.view addSubview:self.chongBtnInCall];
    [self.view addSubview:self.matchTipView];
    [self.view addSubview:self.giftBtnInCall];
    [self.view addSubview:self.moreBtnInCall];
    [self.view addSubview:self.chatButton];
    [self.view addSubview:self.inforView];
    [self.inforView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(16);
        make.top.mas_equalTo(StatusBarHeightConstant);
    }];
    
    self.inforView.userM = self.otherUser;
    
    [self.hangupBtnInCall mas_makeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(24);
        make.right.mas_equalTo(-12);
        make.centerY.equalTo(self.inforView);
    }];
    
    [self.localRenderView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(CGSizeMake(88, 120));
        make.right.mas_equalTo(-12);
        make.top.equalTo(self.inforView.mas_bottom).offset(12);
        
    }];
    
    [self.chatButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(12);
        make.bottom.mas_equalTo(-(SafeAreaInsetsConstantForDeviceWithNotch.bottom+12));
        make.right.mas_greaterThanOrEqualTo(-156);
    }];
    
    
    [self.chatView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(12);
        make.bottom.mas_equalTo(-(SafeAreaInsetsConstantForDeviceWithNotch.bottom + 64));
        make.right.mas_equalTo(-70);
        make.height.mas_lessThanOrEqualTo(260);
    }];
    
   
    [self.chongBtnInCall mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.chatButton);
        make.right.mas_equalTo(-12);
    }];
    
    [self.giftBtnInCall mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.chongBtnInCall);
        make.right.equalTo(self.chongBtnInCall.mas_left).offset(-8);
    }];
    
    [self.moreBtnInCall mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.chongBtnInCall);
        make.right.equalTo(self.giftBtnInCall.mas_left).offset(-8);
    }];
    
    [self.matchTipView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.moreBtnInCall).offset(-12);
        make.bottom.equalTo(self.moreBtnInCall.mas_top).offset(-8);
    }];
    
    
    
    
    // 可用的控件
    NSArray *availbleViews = @[self.localRenderView, self.remoteRenderView, self.hangupBtnInCall, self.giftBtnInCall, self.chongBtnInCall, self.matchTipView, self.moreBtnInCall, self.chatView, self.chatButton, self.inforView];
    [self updateAvailableViews:availbleViews];
    if (self.isSecretAccept){
        [self closeCameraEvent:self.cameraBtnInCall];
    }
    
}

#pragma mark - actions

/// 取消匹配
- (void)cancelMatchEvent:(UIButton *)button
{
    NSLog(@"%s",__func__);
    
    if (CFAbsoluteTimeGetCurrent() - _joinRoom <= 5) {
        [QMUITips showWithText:@"进入闪聊后，5秒内不可以退出房间"];
        return;
    }
    
    // 1、离开房间
    [HLRtcCallKit.sharedInstance leave:^(NSError * _Nullable error) {
        NSLog(@"取消匹配 error = %@", error);
    }];
    // 2、关闭房间
    [HLRtcCallKit.sharedInstance closeChannel:^(NSError * _Nullable error) {
        NSLog(@"关闭房间 error = %@", error);
    }];
    // 3、离开页面
    [self destroyVC];
}
/// 取消呼叫
- (void)cancelCallingEvent:(UIButton *)button
{
    NSLog(@"%s",__func__);
    [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
        NSLog(@"挂断 error = %@", error);
        if (error) {
            [QMUITips showWithText:error.localizedDescription];
        }
        [self destroyVC];
    }];
}
/// 拒绝接听
- (void)rejectBtn:(UIButton *)button
{
    NSLog(@"%s",__func__);
    NSLog(@"当前的HLRtcCallKit.sharedInstance : %zd", HLRtcCallKit.sharedInstance.callStatus);
    
    if (HLRtcCallKit.sharedInstance.callStatus == HLRtcCallStatusCalled) {
        [HLRtcCallKit.sharedInstance reject:^(NSError * _Nullable error) {
            NSLog(@"拒绝接听 error = %@", error);
            
            [self destroyVC];
        }];
    } else {
        [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
            [self destroyVC];
        }];
    }
}
/// 接听
- (void)acceptBtn:(UIButton *)button
{
    if (self.acceptBtn.isHidden){
        return;
    }
    NSLog(@"%s",__func__);
    
    self.statusLabel.hidden = NO;
    self.rejectBtn.hidden = YES;
    self.acceptBtn.hidden = YES;
    self.secretAcceptBtn.hidden = YES;
    
    MJWeakSelf
    [self checkServiceEnable:^(BOOL result) {
        if (result) {
            [HLRtcCallKit.sharedInstance accept:^(NSError * _Nullable error) {
                if (error) {
                    [QMUITips showWithText:@"对方已离线"];
                    [weakSelf destroyVC];
                }
            }];
        }
    }];
    
}

///私密接听
- (void)secretAcceptBtn:(UIButton *)button
{
    self.isSecretAccept = YES;
    [self acceptBtn:button];
}

/// 挂断
- (void)hangupBtnInCall:(UIButton *)button
{
    MJWeakSelf;
    [HLRtcExitView showWithCallback:^(BOOL isSure) {
        if (isSure){
            // 男
            if (weakSelf.initStatus == HLCallStatusJoiningRoom) {
                // 一开始加入闪聊房间 执行离开操作
                [HLRtcCallKit.sharedInstance leave:^(NSError * _Nullable error) {
                    NSLog(@"男方退出闪聊房间");
                    [weakSelf destroyVC];
                }];
            } else {
                // 一开始正常呼叫或者接听 执行挂断操作
                [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
                    NSLog(@"挂断 error = %@", error);
                    [weakSelf destroyVC];
                }];
            }
        }
    }];
}

/// 充值
- (void)rechargeBtnInCall:(UIButton *)button
{
    [HLRtcRechargeView show];
}

/// 礼物
- (void)giftBtnInCall:(UIButton *)button
{
    MJWeakSelf
    [HLGiftContainerView showWithPlaceType:HLGiftPlaceTypeVideo user:self.otherUser callback:^(NSDictionary *info) {
        HLGiftModel *gift = info[@"gift"];
        NSInteger duration = [info[@"userVideoDuration"] intValue];
        if (weakSelf.avaiableInitDuration >= 60) {
            weakSelf.avaiableDuration = duration;
        }
        
        HLGiftLiveListModel *giftModel = [[HLGiftLiveListModel alloc] init];
        HLGiftLiveUserModel *userModel = [[HLGiftLiveUserModel alloc] init];
        
        NSString *giftName = gift.giftName;
        
        giftModel.name = giftName;
        giftModel.type = giftName;
        giftModel.picUrl = gift.giftImgLink;
        giftModel.rewardMsg = [NSString stringWithFormat:@"%@%@",@"送", giftName];
        
        userModel.name = HLRunTime.shareInstance.mine.nickName;
        userModel.iconUrl = HLRunTime.shareInstance.mine.avatar;
        userModel.placegolderImage = [HLUIHelper avatarPlaceholder];
        HLGiftLiveShowModel *giftShowModel = [HLGiftLiveShowModel giftModel:giftModel userModel:userModel];
        [self.customGiftShow addLiveGiftShowModel:giftShowModel];
        
        [self sendGiftMessage:gift];
        
    }];

}


- (void)moreButtonAction:(UIButton *)actionButton
{
    [HLRtcMoreView showWitContentView:self.moreView];
}


- (void)switchCameraEvent:(UIButton *)button
{
    button.selected = !button.selected;
    
    [self.mCamera changeCameraInputDeviceisFront:!button.selected];
    
    [[HLFaceManager shareManager] onCameraChange];
}

- (void)closeCameraEvent:(UIButton *)button
{
    [HLRtcCallKit.sharedInstance enableLocalVideo:button.selected];
    button.selected = !button.selected;
    
    if (button.selected == YES) {
        // 关闭了摄像头
        [self.localRenderView bringSubviewToFront:self.localRenderView.tipLabel];
        self.localRenderView.tipLabel.text = @"您关闭了摄像头";
        [self.localRenderView setNeedsLayout];
    } else {
        self.localRenderView.tipLabel.text = @"";
        [self.localRenderView setNeedsLayout];
    }
    
    [NSUserDefaults.standardUserDefaults setBool:button.selected forKey:@"rtc_is_CloseCamera"];
    [NSUserDefaults.standardUserDefaults synchronize];
}

- (void)smallWindowEvent:(UIButton *)button
{
    if ([self.delegate respondsToSelector:@selector(callShouldBecomeSmallWithController:)]) {
        [self.delegate callShouldBecomeSmallWithController:self];
    }
    
    if (self.status == HLCallStatusCreatingRoom || self.status == HLCallStatusWaitingMan) {
        [HLRtcCallKit.sharedInstance changeLocalView:self.smallWindow.renderView];
    } else if (self.status == HLCallStatusInCall) {
        [HLRtcCallKit.sharedInstance setupRemoteView:self.smallWindow.renderView forUser:self.otherUser.userId];
    }
    
    [self dismissViewControllerAnimated:NO completion:nil];
}

- (void)muteEvent:(UIButton *)button
{
    button.selected = !button.selected;
    [HLRtcCallKit.sharedInstance muteLocalAudio:button.selected];
    
    if (button.selected) {
        [QMUITips showWithText:@"您关闭了麦克风"];
    } else {
        [QMUITips showWithText:@"您开启了麦克风"];
    }
    
    [NSUserDefaults.standardUserDefaults setBool:button.selected forKey:@"rtc_is_CloseMicro"];
    [NSUserDefaults.standardUserDefaults synchronize];
}

- (void)chatButtonEvent:(id)sender
{
    if (!_inputView) {
        _inputView = [[HLRtcInputView alloc] init];
        _inputView.delegate = self;
        [self.view addSubview:self.inputView];
        [self.inputView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.bottom.mas_equalTo(0);
        }];
        MJWeakSelf
        self.inputView.textfield.qmui_keyboardWillChangeFrameNotificationBlock = ^(QMUIKeyboardUserInfo *keyboardUserInfo) {
                [QMUIKeyboardManager handleKeyboardNotificationWithUserInfo:keyboardUserInfo showBlock:^(QMUIKeyboardUserInfo *keyboardUserInfo) {
                    [weakSelf showToolbarViewWithKeyboardUserInfo:keyboardUserInfo];
                } hideBlock:^(QMUIKeyboardUserInfo *keyboardUserInfo) {
                    [weakSelf hideToolbarViewWithKeyboardUserInfo:keyboardUserInfo];
                }];
            };
    }
    [_inputView.textfield becomeFirstResponder];
}

- (void)setupLocalRender:(UIView *)view
{
    [HLRtcCallKit.sharedInstance changeLocalView:view];
}

- (void)setupRemoteRender:(UIView *)view
{
    [HLRtcCallKit.sharedInstance setupRemoteView:view forUser:self.otherUser.userId];
}

- (void)updateRemoteView
{
    [HLRtcCallKit.sharedInstance setupRemoteView:self.remoteRenderView forUser:self.otherUser.userId];
}

#pragma mark - <Private>

- (void)updateAvailableViews:(NSArray *)availbleViews
{
    for (UIView *view in self.view.subviews) {
        if (![availbleViews containsObject:view]) {
            view.hidden = YES;
        }
    }
}

- (void)becomeBigVideoView:(HLRTCVideoView *)videoView {
    
    if (!self.backgroundView.isHidden) {
        return;
    }
    
    [videoView becomeBig];
    
    NSInteger frontIndex = 0;
    NSInteger backIndex = 0;
    HLRTCVideoView *forwardView = [videoView isEqual:self.localRenderView]?self.remoteRenderView:self.localRenderView;
    for (int i = 0; i < self.view.subviews.count; i ++) {
        UIView *view = self.view.subviews[i];
        if ([view isEqual:videoView]) {
            backIndex = i;
        }
        if ([view isEqual:forwardView]) {
            frontIndex = i;
        }
    }
    [self.view exchangeSubviewAtIndex:frontIndex withSubviewAtIndex:backIndex];
    
    [forwardView becomeSmall];
}

- (void)startTimer
{
    if (!self.inCallTimer) {
        _timerCount = 0;
        self.inCallTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
    }
}

- (void)runTimer
{
    _timerCount++;
    
    /**
     * 如果男性可用时长不足，自动挂掉
     */
    if(_timerCount >= (self.avaiableDuration - 3)){
        [QMUITips showWithText:@"您的账号余额不足,自动挂断"];

        MJWeakSelf
        [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
            [weakSelf destroyVC];
        }];
        return;
    }
    
    if ((self.avaiableDuration - _timerCount) == 120){
        [HLRtcExitView showWithTitle:@"温馨提示" Content:@"您还可视频两分钟是否充值" LeftButtonTitle:@"取消" RightButtonTitle:@"充值" Callback:^(BOOL isConfirm) {
            if (!isConfirm){
                [HLRtcRechargeView show];
            }
        }];
    }
    
    if (_timerCount == 10 && self.isFromMatch) {
        self.matchTipView.hidden = NO;
    }
    
    if (_timerCount >= 27 && self.isFromMatch) {
        MJWeakSelf
        [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
            [weakSelf destroyVC];
        }];
        return;
    }

    self.inforView.durationLabel.text = [NSString stringWithFormat:@"视频中 %@", [HLHelper showTimeInCall:_timerCount]];
    
    if (_femaleBlurCurrent > 0 && (_timerCount - _femaleBlurCurrent) > 7){
        [self.femaleBlureView removeFromSuperview];
        self.localRenderView.enableGesture = YES;
        _femaleBlurCurrent = 0;
    }
}

- (void)cleanTimer
{
    if (self.inCallTimer) {
        [self.inCallTimer invalidate];
    }
    self.inCallTimer = nil;
}

/// 销毁页面
- (void)destroyVC
{
    [NSNotificationCenter.defaultCenter removeObserver:self name:UIScreenCapturedDidChangeNotification object:nil];
    [NSNotificationCenter.defaultCenter removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil];
    
    if ([self.delegate respondsToSelector:@selector(callDismissWithController:)]) {
        [self.delegate callDismissWithController:self];
    }
    
    [HLSystemRingTool.shareInstance finishPlay];
    int sessionTime = _timerCount;
    [self cleanTimer];

    [self dismissViewControllerAnimated:YES completion:^{
        if (self.matchCallback){
            self.matchCallback(YES);
        } else if (sessionTime > 3){
            [QMUIHelper executeBlock:^{
                [HLRtcResultView showWithUser:self.otherUser time:[HLHelper showTimeInCall:sessionTime]];
            } oncePerIdentifier:self.otherUser.userId];
            
        }
    }];
}

/// 原语言
- (NSString *)fromLang
{
    NSString *lang = [NSUserDefaults.standardUserDefaults valueForKey:[NSString stringWithFormat:@"%@_lang", self.otherUser.userId?:@""]];
    if (!lang) {
        NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
        if ([language hasPrefix:@"zh"]) {
            [NSUserDefaults.standardUserDefaults setValue:@"vi" forKey:[NSString stringWithFormat:@"%@_lang", self.otherUser.userId]];
            [NSUserDefaults.standardUserDefaults synchronize];
        } else {
            [NSUserDefaults.standardUserDefaults setValue:@"cn" forKey:[NSString stringWithFormat:@"%@_lang", self.otherUser.userId]];
            [NSUserDefaults.standardUserDefaults synchronize];
        }
        
        return language;
    }
    return lang;
}

- (NSString *)toLang
{
    NSString *objectLangCode;
    NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
    if ([language hasPrefix:@"zh"]) { // 汉语
        objectLangCode = @"cn";
    } else if ([language hasPrefix:@"vi"]) { // 越南语
        objectLangCode = @"vi";
    } else {
        objectLangCode = @"cn";
    }
    
    return objectLangCode;
}


- (void)tapAction
{
    if ([self.inputView.textfield isFirstResponder]) {
        [self.inputView.textfield resignFirstResponder];
    } else {
        self.isHideViewInCall = !_isHideViewInCall;
        [self updateViewInCallWithHide:_isHideViewInCall];
    }
}

- (void)updateViewInCallWithHide:(BOOL)isHide
{
    self.inforView.hidden = isHide;
    self.moreBtnInCall.hidden = isHide;
    self.chatButton.hidden = isHide;
    self.hangupBtnInCall.hidden = isHide;
    self.chatView.hidden = isHide;
}

#pragma mark - <HLGiftViewDelegate>

#pragma mark - <HLRTCViceoViewDelegate>

- (void)onTapVideoView:(HLRTCVideoView *)videoView
{
    [self tapAction];
    if (videoView.isSmall) {
        [self becomeBigVideoView:videoView];
    }
}

#pragma mark - <HLRtcCallKitDelegate>

/// 接受邀请的回调 用户进入房间
/// @param userID 接受者
- (void)onUserEnter:(NSString *)userID
{
    
    [HLSystemRingTool.shareInstance finishPlay]; // 铃声消失
    self.status = HLCallStatusInCall; // 变更状态
    
    /*
     插入一条公告消息
     */
    HLRtcMessageModel *msg = [[HLRtcMessageModel alloc] init];
    msg.type = 1000;
    msg.ext = @"官方：严禁出现色情，欺诈，诱导添加联系方式，转账，诈骗，引导到其他软件行为，联系客服举报有奖！共创绿色文明环境！";
    [self.chatView addMessage:msg];
    
    [HLRtcCallKit.sharedInstance adjustPlaybackSignalVolume:400];
    [HLRtcCallKit.sharedInstance setupRemoteView:self.remoteRenderView forUser:self.otherUser.userId?:userID];
    
    [self startTimer];
}

/// 接受邀请
/// @param userID 接受者
- (void)onUserAccept:(NSString *)userID
{
    
}

/// 拒绝邀请的回调
/// @param userID 拒绝者
- (void)onUserReject:(NSString *)userID
{
    [HLSystemRingTool.shareInstance finishPlay];
    self.statusLabel.text = @"对方拒绝了您的通话请求！";
    self.statusLabel.centerX = self.view.middleX;
    
    [QMUITips showWithText:@"对方拒绝了您的通话请求！"];
    
    [HLRtcCallKit.sharedInstance cancel:^(NSError * _Nullable error) {
        NSLog(@"因对方拒绝接听挂断 error = %@", error);
        [self destroyVC];
    }];
}

/// 取消邀请的回调
/// @param userID 邀请方
- (void)onUserCancel:(NSString *)userID
{
    if (_status != HLCallStatusCalled) {
        return;
    }
    
    [self destroyVC];
}

- (void)onUserBusy:(NSString *)userID
{
    [HLSystemRingTool.shareInstance finishPlay];
    [QMUITips showWithText:@"对方已离线"];
    [self specialHangup];
}

/// 通话结束
- (void)onCallEnd
{
    NSLog(@"%s", __func__);
    [self cleanTimer];
    if (self.initStatus == HLCallStatusCreatingRoom) {
        self.status = self.initStatus;
    } else {
        [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
            [self destroyVC];
        }];
    }
}

- (void)onDisconnect:(NSError *)reason
{
    NSLog(@"%s", __func__);
}

/// 呼叫请求已被其他端接收的回调
- (void)onOtherClientAccept;
{
    [self destroyVC];
    NSLog(@"%s", __func__);
}

/// 呼叫请求已被其他端拒绝的回调
- (void)onOtherClientReject;
{
    [self destroyVC];
    NSLog(@"%s", __func__);
}

/// 用户离开的回调.
/// @param userID 用户userID
- (void)onUserLeave:(NSString *)userID
{
    MJWeakSelf
    [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
        NSLog(@"挂断 error = %@", error);
        if (error) {
            [QMUITips showWithText:error.localizedDescription];
        }
        [weakSelf destroyVC];
    }];
}

/// 用户异常离开的回调
/// @param userID 用户userID
- (void)onUserDisconnect:(NSString *)userID
{
    [self cleanTimer];
    MJWeakSelf
    [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
        [weakSelf destroyVC];
    }];
}

- (void)onCallingTimeOut
{
    [QMUITips showWithText:@"呼叫超时"];
    [self destroyVC];
}

- (void)onError:(NSError *)error
{
    [QMUITips showWithText:@"对方已离线"];
    [self destroyVC];
}

- (void)onSelfError:(NSError *)error
{
    [self destroyVC];
}

- (void)onCameraAvailable:(BOOL)available userID:(NSString *)userID;
{
    if (self.callType == HLRtcCallTypeVideo) {
        NSString *object = @"对方";
        
        if (available) {
            NSString *msg = [object stringByAppendingString:@"开启了摄像头"];
            [QMUITips showWithText:msg];
            self.remoteRenderView.tipLabel.text = @"";
            [self.remoteRenderView setNeedsLayout];
            
        } else {
            NSString *msg = [object stringByAppendingString:@"关闭了摄像头"];
            [QMUITips showWithText:msg];
            
            [self.remoteRenderView bringSubviewToFront:self.remoteRenderView.tipLabel];
            self.remoteRenderView.tipLabel.text = msg;
            [self.remoteRenderView setNeedsLayout];
        }
    }
}

- (void)onUserNetworkQuality:(NSDictionary<NSString *,NERtcNetworkQualityStats *> *)stats
{
    /*
     kNERtcNetworkQualityUnknown = 0,
     网络质量极好
     kNERtcNetworkQualityExcellent,
     用户主观感觉和 excellent 差不多，但码率可能略低于 excellent
     kNERtcNetworkQualityGood,
     用户主观感受有瑕疵但不影响沟通
     kNERtcNetworkQualityPoor,
     勉强能沟通但不顺畅
     kNERtcNetworkQualityBad,
     网络质量非常差，基本不能沟通
     kNERtcNetworkQualityVeryBad,
     完全无法沟通
     kNERtcNetworkQualityDown,
     */
    NERtcNetworkQualityStats *myRtcNetQuality = stats[HLRunTime.shareInstance.mine.userId];
    NERtcNetworkQualityStats *otherRtcNetQuality = stats[self.otherUser.userId];
    
    if (myRtcNetQuality) {
        switch (myRtcNetQuality.txQuality) {
            case kNERtcNetworkQualityExcellent://网络质量极好
            {
            }
                break;
            case kNERtcNetworkQualityGood://用户主观感觉和 excellent 差不多，但码率可能略低于 excellent
            {
            }
                break;
            case kNERtcNetworkQualityPoor://用户主观感受有瑕疵但不影响沟通
            {
            }
                break;
            case kNERtcNetworkQualityBad://勉强能沟通但不顺畅
            {
            }
                break;
            case kNERtcNetworkQualityVeryBad://网络质量非常差，基本不能沟通
            {
                [QMUITips showWithText:@"您的网络非常差"];
            }
                break;
            case kNERtcNetworkQualityDown://完全无法沟通
            {
                [QMUITips showWithText:@"您的网络已经差到无法沟通"];
            }
                break;
            case kNERtcNetworkQualityUnknown:
            {
                
            }
                break;
                
            default:
                break;
        }
    }
    if (otherRtcNetQuality) {
        switch (otherRtcNetQuality.txQuality) {
            case kNERtcNetworkQualityExcellent://网络质量极好
            {
            }
                break;
            case kNERtcNetworkQualityGood://用户主观感觉和 excellent 差不多，但码率可能略低于 excellent
            {
            }
                break;
            case kNERtcNetworkQualityPoor://用户主观感受有瑕疵但不影响沟通
            {
            }
                break;
            case kNERtcNetworkQualityBad://勉强能沟通但不顺畅
            {
            }
                break;
            case kNERtcNetworkQualityVeryBad://网络质量非常差，基本不能沟通
            {
                [QMUITips showWithText:@"对方网络非常差"];
            }
                break;
            case kNERtcNetworkQualityDown://完全无法沟通
            {
                [QMUITips showWithText:@"对方网络已经差到无法沟通"];
            }
                break;
            case kNERtcNetworkQualityUnknown:
            {
            }
                break;
                
            default:
                break;
        }
    }
}

#pragma mark - <NIMChatManagerDelegate>

- (void)onReceiveCustomSystemNotification:(NIMCustomSystemNotification *)notification
{
    NSLog(@"%s", __FUNCTION__);
    if (notification.content) {
        NSDictionary *dict = [notification.content mj_JSONObject];
        
        NSInteger type = 0;
        id object = [dict objectForKey:@"msgType"];
        if ([object isKindOfClass:[NSString class]] ||
            [object isKindOfClass:[NSNumber class]])
        {
            type = [object integerValue];
        }
        
        switch (type) {
            case 10:
            {
                // 推送给违规女用户 进行挂断
                [QMUITips showWithText:@"系统鉴定你可能存在违规情况"];
                [self specialHangup];
                /*
                 退出
                 */
                [HLHelper logout];
                [HLUIHelper setRootLogin];
                [NIMSDK.sharedSDK.loginManager logout:^(NSError * _Nullable error) {
                }];
            }
                break;
            case 12:
            {
                // 推送给违规女用户 取content展示
                NSDictionary *ext = [dict[@"ext"] mj_JSONObject];
                [QMUITips showWithText:ext[@"content"]];
            }
                break;
            case 11:
            {
                // 推送给男用户 做毛玻璃遮挡
                NSDictionary *ext = [dict[@"ext"] mj_JSONObject];
                [QMUITips showWithText:ext[@"content"]];
                _femaleBlurCurrent = _timerCount;
                self.localRenderView.enableGesture = NO;
                [self.remoteRenderView addSubview:self.femaleBlureView];
            }
                break;
                
            default:
                break;
        }
    }
}

- (void)onClickCancelCalling
{
    [self cancelCallingEvent:nil];
}

- (void)onClickReject
{
    [self rejectBtn:nil];
}

- (void)onClickHangup
{
    [self hangupBtnInCall:nil];
}

- (void)onClickAccept
{
    [self acceptBtn:nil];
}

- (void)onClickMicro:(QMUIButton *)button
{
    [self muteEvent:button];
}

- (void)onClickSpeaker:(QMUIButton *)button
{
    button.selected = !button.selected;
    [HLRtcCallKit.sharedInstance setLoudSpeakerMode:!button.selected error:nil];
}


#pragma mark - <禁止录屏、截屏>

- (void)screenHot
{
    if (@available(iOS 11.0, *)) {
        if (UIScreen.mainScreen.isCaptured) {
            
            [NSNotificationCenter.defaultCenter postNotificationName:HLScreenChangedNotification object:nil userInfo:@{@"type" : @(1)}];
            [QMUITips showWithText:@"视频期间不可录屏"];
            [self specialHangup];
        } else {
            /// 截屏
            [NSNotificationCenter.defaultCenter postNotificationName:HLScreenChangedNotification object:nil userInfo:@{@"type" : @(0)}];
            [QMUITips showWithText:@"视频期间不可截屏"];
            [self specialHangup];
        }
    }
}

/// 特殊的关闭
- (void)specialHangup
{
    [HLRtcCallKit.sharedInstance hangup:^(NSError * _Nullable error) {
        NSLog(@"挂断 error = %@", error);
        [self destroyVC];
    }];
}

- (void)applicationDidEnterBackground
{
    [self specialHangup];
}

#pragma mark - <隐私>

- (void)checkServiceEnable:(void(^)(BOOL result))block
{
    if (UIScreen.mainScreen.isCaptured) {
        [QMUITips showWithText:@"录屏期间不可视频"];
        block(NO);
        return;
    }

    [HLHelper authorizationStatus];
    
    if (block) {
        block(YES);
    }
}

- (void)showToolbarViewWithKeyboardUserInfo:(QMUIKeyboardUserInfo *)keyboardUserInfo {
    if (keyboardUserInfo) {
        self.inputView.hidden = NO;
        [QMUIKeyboardManager animateWithAnimated:YES keyboardUserInfo:keyboardUserInfo animations:^{
            CGFloat distanceFromBottom = keyboardUserInfo.isFloatingKeyboard ? 0 : [QMUIKeyboardManager distanceFromMinYToBottomInView:self.view keyboardRect:keyboardUserInfo.endFrame];
            
            CGFloat bottomConstant = distanceFromBottom;
            self.inputView.layer.transform = CATransform3DMakeTranslation(0, -bottomConstant, 0);
            [self.chatView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.bottom.mas_equalTo(-(bottomConstant + 48));
            }];
        } completion:NULL];
    }
}

- (void)hideToolbarViewWithKeyboardUserInfo:(QMUIKeyboardUserInfo *)keyboardUserInfo {
    if (keyboardUserInfo) {
        [QMUIKeyboardManager animateWithAnimated:YES keyboardUserInfo:keyboardUserInfo animations:^{
            self.inputView.layer.transform = CATransform3DIdentity;
            [self.chatView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.bottom.mas_equalTo(-(SafeAreaInsetsConstantForDeviceWithNotch.bottom + 64));
            }];
            self.inputView.hidden = YES;
        } completion:nil];
    }
}


- (void)rtcInputView:(HLRtcInputView *)inputView willSend:(NSString *)string
{
    if (!string.length) {
        return;
    }
    
    NSString *text = string;
    // 过滤空内容
    if (text.length == 0) {
        [QMUITips showWithText:@"发送的内容为空"];
        return;
    }
    
    // 检查源语言与目标语言一致，若一致不翻译
    if ([self.targetLang isEqualToString:HLHelper.language]) {
        [self _sendText:text needTranslacting:NO];
        return;
    }
    
    BOOL containsChinese = text.containsChinese; // 用户输入的内容是否包含中文
    BOOL containsNonChineseLanguageText = text.containsNonChineseLanguageText; // 用户输入的内容是否包含非中文
    
    // 外文+任意（中文、表情、数字、符号），翻译后发送
    if (containsNonChineseLanguageText) {
        // 翻译
        [self _sendText:text needTranslacting:YES];
        return;
    }

    // 中文+任意（表情、数字、符号）
    if (containsChinese) {
        // 不翻译 直接发送给对方
        [self _sendText:text needTranslacting:NO];
        return;
    }
    
    // 表情+任意（数字、符号）
    if (text.containsEmoticon) {
        // 不翻译 直接发送给对方
        [self _sendText:text needTranslacting:NO];
        return;
    }
    
    // 数字+符号
    // 不翻译 直接发送给对方
    [self _sendText:text needTranslacting:NO];
}

- (void)_sendText:(NSString *)text needTranslacting:(BOOL)need
{
    if (need) {
        // 从自己的语言翻译到对方的语言
        NSDictionary *params = @{
            @"body" : text,
            @"targetLang": self.targetLang,
            @"sourceLang": [HLHelper language]
        };
        YMTranslacteRequest *transRequest = [YMTranslacteRequest.alloc initWithType:YMTranslacteRequestTypeTranslacte];
        transRequest.params = params;
        [transRequest startWithCompletionBlockWithSuccess:^(__kindof YMTranslacteRequest * _Nonnull request) {
            NSLog(@"[debug] tr %@", request.result);
            if (request.isSuccess){
                [self sendMessage:request.tranlacteResult local:text];
            }
        } failure:nil];
    } else {
        [self sendMessage:text local:text];
    }
}

#pragma mark - 文字消息收发
// 视频中发送文字
- (void)sendMessage:(NSString *)text local:( NSString * _Nullable )local  {
    
    /*
     发送给对方的ext内容
     */
    NSDictionary *extObject = @{
        @"origin" : local?:@"",
        @"translate" : text?:@""
    };
    
    NSString *extJsonString = extObject.mj_JSONString;
    
    NSDictionary *json = @{
        @"cid" : @(100),
        @"ext" : extJsonString, // 转成json字符串
        @"fromName" : HLRunTime.shareInstance.mine.nickName?:@"",
    };
    // 发送
    [HLRtcCallKit.sharedInstance sendCustomSingleControl:json.mj_JSONString];
    
    /*
     插入到UI
     */
    HLRtcMessageModel *msg = [[HLRtcMessageModel alloc] init];
    msg.type = 100;
    msg.ext = local?:text;
    msg.from = HLRunTime.shareInstance.mine.userId;
    msg.fromName = HLRunTime.shareInstance.mine.nickName;
    msg.fromAvatar = HLRunTime.shareInstance.mine.avatar;
    msg.localExt = @{@"originContent":local};
    msg.text = local;
    [self.chatView addMessage:msg];
}

- (void)sendGiftMessage:(HLGiftModel *)model
{
    /*
     发送给对方
     */
    
    NSDictionary *json = @{
        @"cid" : @(101),
        @"ext" : @{
            @"giftName" : model.giftName,
            @"giftImgLink" : model.giftImgLink,
        }.mj_JSONString,
        @"fromName" : HLRunTime.shareInstance.mine.nickName,
        @"fromAvatar" : HLRunTime.shareInstance.mine.avatar
    };
    
    [HLRtcCallKit.sharedInstance sendCustomSingleControl:json.mj_JSONString];
}


// 自定义信令通知
- (void)onRecvCustomSingleControl:(NIMSignalingNotifyInfo *)notifyResponse {
    
    
    if (notifyResponse.eventType == NIMSignalingEventTypeContrl) {
        NSData *data = [notifyResponse.customInfo dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data
                                                             options:0
                                                               error:nil];
        NSInteger cid = 0;
        if ([dict[@"cid"] isKindOfClass:NSNumber.class]) {
            cid = [dict[@"cid"] integerValue];
        }
        if (cid == 100) {
            HLRtcMessageModel *msg = [HLRtcMessageModel mj_objectWithKeyValues:dict];
            NSData *body = [msg.ext dataUsingEncoding:NSUTF8StringEncoding];
            if (body) {
                id bodyDict = [NSJSONSerialization JSONObjectWithData:body
                                                                         options:0
                                                                           error:nil];
                if ([bodyDict isKindOfClass:NSDictionary.class]) {
                    id origin = bodyDict[@"origin"];
                    id translate = bodyDict[@"translate"];
                    msg.text = translate;
                    msg.localExt = @{@"originContent":origin};
                } else {
                    msg.text = msg.ext;
                }
            } else {
                msg.text = msg.ext;
            }
            msg.type = 100;
            msg.from = self.otherUser.userId;
            msg.fromName = self.otherUser.nickName;
            msg.fromAvatar = self.otherUser.avatar;
            msg.messageId = [HLRtcMessageModel randomID];
            [self.chatView addMessage:msg];
            
        } else if (cid == 101) {
            HLGiftLiveListModel *giftModel = [[HLGiftLiveListModel alloc] init];
            HLGiftLiveUserModel *userModel = [[HLGiftLiveUserModel alloc] init];
            
            HLGiftAttachment *model = [HLGiftAttachment mj_objectWithKeyValues:dict[@"ext"]];
            NSString *giftName = model.giftName;

            giftModel.name = giftName;
            giftModel.type = giftName;
            giftModel.picUrl = model.giftImgLink;
            giftModel.giftDynamicUrl = model.giftAnimateLink;
            giftModel.rewardMsg = [NSString stringWithFormat:@"%@%@",@"送", giftName];

            userModel.name = dict[@"fromName"]?:self.otherUser.nickName;
            userModel.iconUrl = dict[@"fromAvatar"]?:[HLUIHelper avatarPlaceholder];
            userModel.placegolderImage = [HLUIHelper avatarPlaceholder];
            HLGiftLiveShowModel *giftShowModel = [HLGiftLiveShowModel giftModel:giftModel userModel:userModel];
            [self.customGiftShow addLiveGiftShowModel:giftShowModel];
        }
    }
}

#pragma marl UIViewControllerDelegate

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}
@end
